package com.econ.powercloud.ems.service.biz;

import com.econ.powercloud.common.base.facade.enums.StatusType;
import com.econ.powercloud.common.base.facade.exception.CommonRuntimeException;
import com.econ.powercloud.common.base.facade.util.JacksonUtil;
import com.econ.powercloud.ems.common.enums.DitTypeEnum;
import com.econ.powercloud.ems.common.util.IdWorker;
import com.econ.powercloud.ems.constant.SysConstant;
import com.econ.powercloud.ems.dal.entity.EmsCombination;
import com.econ.powercloud.ems.dal.entity.EmsCombinationDetail;
import com.econ.powercloud.ems.pojo.DitDataExtraVO;
import com.econ.powercloud.ems.pojo.DitDataVO;
import com.econ.powercloud.ems.pojo.EmsCombinationDetailVO;
import com.econ.powercloud.ems.pojo.EmsCombinationVO;
import com.econ.powercloud.ems.pojo.requestVO.EmsCombinationDetailRequestVO;
import com.econ.powercloud.ems.pojo.requestVO.EmsCombinationRequestVO;
import com.econ.powercloud.ems.service.dao.EmsCombinationDAO;
import com.econ.powercloud.ems.service.dao.EmsCombinationDetailDAO;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author : zjf
 * @Description :
 * @Date : 2022/4/18 14:38
 * @Modified by : zjf
 */
@Service
public class EmsCombinationService {

    @Autowired
    private EmsCombinationDAO emsCombinationDAO;
    @Autowired
    private EmsCombinationDetailDAO emsCombinationDetailDAO;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private DeviceService deviceService;

    /**
     * 根据组合类型与储能站获取已保存的组合
     */
    public List<EmsCombinationVO> getCombinationListByStationIdAndType(Integer type, String stationId){
        List<EmsCombination> combinationList = emsCombinationDAO.selectListByTypeAndStationId(type,stationId) ;
        if(CollectionUtils.isEmpty(combinationList)){
            return Collections.emptyList();
        }
        return JacksonUtil.convertToList(combinationList, EmsCombinationVO.class);
    }

    /**
     * 根据组合id获取对应的查询点号详情
     */
    public List<EmsCombinationDetailVO> getCombinationDetailListByCombinationId(String combinationId){
        List<EmsCombinationDetail> detailList = emsCombinationDetailDAO.selectListByCombinationId(combinationId);
        if(CollectionUtils.isEmpty(detailList)){
            return Collections.emptyList();
        }
        List<DitDataVO> ditList = detailList.stream().map(d-> DitDataVO.builder()
                .initDeviceCode(d.getInitDeviceCode()).ditType(d.getDitType()).dit(d.getPid().replace(d.getInitDeviceCode() + SysConstant.SPOT,""))
                .build()).collect(Collectors.toList());
        //查找点号的基本信息
        List<DitDataExtraVO> extraVOList = deviceService.getDitExtraByDitDataList(ditList);
        Map<String,DitDataExtraVO> extraMap = extraVOList.stream().collect(Collectors.toMap(d->d.getInitDeviceCode() + SysConstant.SPOT + d.getDit(), p->p,(p1, p2)->p1));
        List<EmsCombinationDetailVO> result = Lists.newArrayList();
        detailList.stream().forEach(d->{
            DitDataExtraVO extraVO = extraMap.get(d.getInitDeviceCode() + SysConstant.SPOT + d.getDit());
            result.add(EmsCombinationDetailVO.builder()
                    .id(d.getId()).combinationId(d.getCombinationId()).pid(d.getPid())
                    .pidName(d.getPidName()).initDeviceCode(d.getInitDeviceCode())
                    .deviceCode(extraVO == null?null:extraVO.getDeviceCode())
                    .deviceName(extraVO == null?null:extraVO.getDeviceName())
                    .ditType(d.getDitType()).ditTypeName(DitTypeEnum.getDescFromCode(d.getDitType()))
                    .dit(d.getDit()).ditName(extraVO == null? null : extraVO.getDitName())
                    .unit(d.getUnit()).gmtCreate(d.getGmtCreate()).gmtModify(d.getGmtModify())
                    .build());
        });
        return result;
    }

    /**
     * 删除已保存的组合
     */
    @Transactional(rollbackFor = Exception.class)
    public String deleteByCombinationId(String combinationId){
        EmsCombination combination = emsCombinationDAO.getById(combinationId);
        Assert.notNull(combination, "删除失败,该组合不存在!");
        emsCombinationDAO.getBaseMapper().deleteById(combinationId);
        emsCombinationDetailDAO.deleteByCombinationId(combinationId);
        return combinationId;
    }

    /**
     * 新增组合
     * @return : 组合id
     */
    @Transactional(rollbackFor = Exception.class)
    public String addCombination(EmsCombinationRequestVO<EmsCombinationDetailRequestVO> requestVO){
        List<EmsCombination> combinationList = emsCombinationDAO.selectListByTypeAndStationId(requestVO.getType(),requestVO.getStationId());
        //判断该储能站下该类型的个数
        if(CollectionUtils.isNotEmpty(combinationList)){
            if(combinationList.size() > SysConstant.MAX_COMBINATION_NUM){
                throw new CommonRuntimeException(StatusType.FAIL,"组合最多保存30个，请删除后再保存!");
            }
            List<String> combinationNameList = combinationList.stream().map(EmsCombination::getCombinationName).collect(Collectors.toList());
            if(combinationNameList.contains(requestVO.getCombinationName())){
                throw new CommonRuntimeException(StatusType.FAIL,"组合名称已存在!");
            }
        }
        String combinationId = idWorker.nextId()+"";
        EmsCombination emsCombination = EmsCombination.builder()
                .combinationId(combinationId).energyStationId(requestVO.getStationId())
                .combinationName(requestVO.getCombinationName()).type(requestVO.getType())
                .gmtCreate(System.currentTimeMillis()).gmtModify(System.currentTimeMillis())
                .build();
        emsCombinationDAO.save(emsCombination);
        List<EmsCombinationDetail> emsCombinationDetails = this.getCombinationDetailListByCondition(requestVO.getDetailRequestVOS(),combinationId);
        emsCombinationDetailDAO.saveBatch(emsCombinationDetails);
        return combinationId;
    }

    /**
     * 修改组合
     */
    @Transactional(rollbackFor = Exception.class)
    public String modifyCombination(EmsCombinationRequestVO requestVO){
        List<EmsCombination> combinationList = emsCombinationDAO.selectListByTypeAndStationId(requestVO.getType(),requestVO.getStationId());
        List<String> requestCombinationList = combinationList.stream().filter(d -> d.getCombinationId().equals(requestVO.getStationId()))
                .map(EmsCombination::getCombinationName).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(requestCombinationList)){
            throw new CommonRuntimeException(StatusType.FAIL,"未找到需要修改的组合!");
        }
        if(CollectionUtils.isEmpty(requestVO.getDetailRequestVOS())){
            throw new CommonRuntimeException(StatusType.FAIL,"该组合点号数据为空!");
        }
        //判断名称是否重复
        List<String> combinationNameList = combinationList.stream().filter(d -> !d.getCombinationId().equals(requestVO.getStationId()))
                .map(EmsCombination::getCombinationName).collect(Collectors.toList());
        if(combinationNameList.contains(requestVO.getCombinationName())){
            throw new CommonRuntimeException(StatusType.FAIL,"组合名称已存在!");
        }
        EmsCombination emsCombination = EmsCombination.builder()
                .combinationId(requestVO.getCombinationId()).energyStationId(requestVO.getStationId())
                .combinationName(requestVO.getCombinationName()).type(requestVO.getType())
                .gmtModify(System.currentTimeMillis())
                .build();
        emsCombinationDAO.save(emsCombination);
        List<EmsCombinationDetail> emsCombinationDetails = this.getCombinationDetailListByCondition(requestVO.getDetailRequestVOS(),requestVO.getCombinationId());
        //先删除在插入
        emsCombinationDetailDAO.deleteByCombinationId(requestVO.getCombinationId());
        emsCombinationDetailDAO.saveBatch(emsCombinationDetails);
        return requestVO.getCombinationId();
    }

    /**
     * 通过点号类型来新增/修改组合
     * @return : 组合id
     */
    @Transactional(rollbackFor = Exception.class)
    public String addCombinationByDitType(EmsCombinationRequestVO<DitDataVO> requestVO){
        List<EmsCombination> combinationList = emsCombinationDAO.selectListByTypeAndStationId(requestVO.getType(),requestVO.getStationId());
        //判断该储能站下该类型的个数
        if(CollectionUtils.isNotEmpty(combinationList)){
            if(combinationList.size() > SysConstant.MAX_COMBINATION_NUM){
                throw new CommonRuntimeException(StatusType.FAIL,"组合最多保存30个，请删除后再保存!");
            }
            List<String> combinationNameList = combinationList.stream().map(EmsCombination::getCombinationName).collect(Collectors.toList());
            if(combinationNameList.contains(requestVO.getCombinationName())){
                throw new CommonRuntimeException(StatusType.FAIL,"组合名称已存在!");
            }
        }
        String combinationId = idWorker.nextId()+"";
        EmsCombination emsCombination = EmsCombination.builder()
                .combinationId(combinationId).energyStationId(requestVO.getStationId())
                .combinationName(requestVO.getCombinationName()).type(requestVO.getType())
                .gmtCreate(System.currentTimeMillis()).gmtModify(System.currentTimeMillis())
                .build();
        emsCombinationDAO.save(emsCombination);
        //存数据库表数据
        emsCombinationDetailDAO.saveBatch(getCombinationDetailListByDitDataVOS(requestVO.getDetailRequestVOS(),combinationId));
        return combinationId;
    }

    /**
     * 修改组合
     */
    @Transactional(rollbackFor = Exception.class)
    public String modifyCombinationByDitType(EmsCombinationRequestVO<DitDataVO> requestVO){
        List<EmsCombination> combinationList = emsCombinationDAO.selectListByTypeAndStationId(requestVO.getType(),requestVO.getStationId());
        List<String> requestCombinationList = combinationList.stream().filter(d -> d.getCombinationId().equals(requestVO.getStationId()))
                .map(EmsCombination::getCombinationName).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(requestCombinationList)){
            throw new CommonRuntimeException(StatusType.FAIL,"未找到需要修改的组合!");
        }
        if(CollectionUtils.isEmpty(requestVO.getDetailRequestVOS())){
            throw new CommonRuntimeException(StatusType.FAIL,"该组合点号数据为空!");
        }
        //判断名称是否重复
        List<String> combinationNameList = combinationList.stream().filter(d -> !d.getCombinationId().equals(requestVO.getStationId()))
                .map(EmsCombination::getCombinationName).collect(Collectors.toList());
        if(combinationNameList.contains(requestVO.getCombinationName())){
            throw new CommonRuntimeException(StatusType.FAIL,"组合名称已存在!");
        }
        EmsCombination emsCombination = EmsCombination.builder()
                .combinationId(requestVO.getCombinationId()).energyStationId(requestVO.getStationId())
                .combinationName(requestVO.getCombinationName()).type(requestVO.getType())
                .gmtModify(System.currentTimeMillis())
                .build();
        emsCombinationDAO.save(emsCombination);
        //先删除在插入
        emsCombinationDetailDAO.deleteByCombinationId(requestVO.getCombinationId());
        emsCombinationDetailDAO.saveBatch(getCombinationDetailListByDitDataVOS(requestVO.getDetailRequestVOS(),requestVO.getCombinationId()));
        return requestVO.getCombinationId();
    }

    private List<EmsCombinationDetail> getCombinationDetailListByDitDataVOS(List<DitDataVO> list,String combinationId){
        //查找点号的基本信息
        List<DitDataExtraVO> extraVOList = deviceService.getDitExtraByDitDataList(list);
        Map<String,DitDataExtraVO> extraMap = extraVOList.stream().collect(Collectors.toMap(d->d.getInitDeviceCode() + SysConstant.SPOT + d.getDit(), p->p,(p1, p2)->p1));
        //存数据库表数据
        List<EmsCombinationDetail> emsCombinationDetails = list.stream().map(d->{
            DitDataExtraVO extraVO = extraMap.get(d.getInitDeviceCode() + SysConstant.SPOT + d.getDit());
            return EmsCombinationDetail.builder()
                    .combinationId(combinationId).pid(d.getInitDeviceCode() + SysConstant.SPOT + d.getDit())
                    .pidName(extraVO == null?null:(extraVO.getDeviceName()+extraVO.getDitName()))
                    .initDeviceCode(d.getInitDeviceCode())
                    .ditType(d.getDitType())
                    .dit(d.getDit())
                    .unit(extraVO == null?null:extraVO.getUnit())
                    .gmtCreate(System.currentTimeMillis()).gmtModify(System.currentTimeMillis())
                    .build();
        }).collect(Collectors.toList());
        return emsCombinationDetails;
    }

    private List<EmsCombinationDetail> getCombinationDetailListByCondition(List<EmsCombinationDetailRequestVO> detailRequestVOS, String combinationId){
        List<EmsCombinationDetail> emsCombinationDetails = Lists.newArrayList();
        detailRequestVOS.stream().forEach(d->{
            emsCombinationDetails.add(EmsCombinationDetail.builder()
                    .combinationId(combinationId).pid(d.getPid()).pidName(d.getPidName())
                    .initDeviceCode(d.getInitDeviceCode()).ditType(DitTypeEnum.YC.getCode())
                    .dit(d.getPid().replace(d.getInitDeviceCode() + SysConstant.SPOT,""))
                    .unit(d.getUnit())
                    .gmtCreate(System.currentTimeMillis()).gmtModify(System.currentTimeMillis())
                    .build());
        });
        return emsCombinationDetails;
    }

}
